
package com.bluelinelabs.conductor.demo.controllers;

import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;

import com.bluelinelabs.conductor.conductor.changehandler.AnimatorChangeHandler;

/**
 * lipeiquan
 *
 * @since 2021-05-06
 */
public class CircularRevealChangeHandler extends AnimatorChangeHandler {
    private static final String KEY_CX = "CircularRevealChangeHandler.cx";
    private static final String KEY_CY = "CircularRevealChangeHandler.cy";

    private int cx;
    private int cy;

    public CircularRevealChangeHandler() { }

    /**
     * Constructor that will create a circular reveal from the center of the fromView parameter.
     * @param fromView The view from which the circular reveal should originate
     * @param containerView The view that hosts fromView
     */
    public CircularRevealChangeHandler( Component fromView,  Component containerView) {
        this(fromView, containerView, DEFAULT_ANIMATION_DURATION);
    }

    /**
     * Constructor that will create a circular reveal from the center of the fromView parameter.
     * @param fromView The view from which the circular reveal should originate
     * @param containerView The view that hosts fromView
     * @param duration The duration of the animation
     */
    public CircularRevealChangeHandler( Component fromView,  Component containerView, long duration) {
        this(fromView, containerView, duration, true);
    }

    /**
     * Constructor that will create a circular reveal from the center of the fromView parameter.
     * @param fromView The view from which the circular reveal should originate
     * @param containerView The view that hosts fromView
     * @param removesFromViewOnPush If true, the view being replaced will be removed from the view hierarchy on pushes
     */
    public CircularRevealChangeHandler( Component fromView,  Component containerView, boolean removesFromViewOnPush) {
        this(fromView, containerView, DEFAULT_ANIMATION_DURATION, removesFromViewOnPush);
    }


    /**
     * Constructor that will create a circular reveal from the center of the fromView parameter.
     * @param fromView The view from which the circular reveal should originate
     * @param containerView The view that hosts fromView
     * @param duration The duration of the animation
     * @param removesFromViewOnPush If true, the view being replaced will be removed from the view hierarchy on pushes
     */
    public CircularRevealChangeHandler( Component fromView,  Component containerView, long duration, boolean removesFromViewOnPush) {
        super(duration, removesFromViewOnPush);

        int[] fromLocation = new int[2];
        fromView.getLocationOnScreen();
//        fromView.getLocationOnScreen(fromLocation);

        int[] containerLocation = new int[2];
        containerView.getLocationOnScreen();
//        containerView.getLocationInWindow(containerLocation);

        int relativeLeft = fromLocation[0] - containerLocation[0];
        int relativeTop  = fromLocation[1] - containerLocation[1];

        cx = fromView.getWidth() / 2 + relativeLeft;
        cy = fromView.getHeight() / 2 + relativeTop;
    }

    /**
     * Constructor that will create a circular reveal from the center point passed in.
     * @param cx The center's x-axis
     * @param cy The center's y-axis
     */
    public CircularRevealChangeHandler(int cx, int cy) {
        this(cx, cy, DEFAULT_ANIMATION_DURATION, true);
    }

    /**
     * Constructor that will create a circular reveal from the center point passed in.
     * @param cx The center's x-axis
     * @param cy The center's y-axis
     * @param duration The duration of the animation
     */
    public CircularRevealChangeHandler(int cx, int cy, long duration) {
        this(cx, cy, duration, true);
    }

    /**
     * Constructor that will create a circular reveal from the center point passed in.
     * @param cx The center's x-axis
     * @param cy The center's y-axis
     * @param removesFromViewOnPush If true, the view being replaced will be removed from the view hierarchy on pushes
     */
    public CircularRevealChangeHandler(int cx, int cy, boolean removesFromViewOnPush) {
        this(cx, cy, DEFAULT_ANIMATION_DURATION, removesFromViewOnPush);

    }

    /**
     * Constructor that will create a circular reveal from the center point passed in.
     * @param cx The center's x-axis
     * @param cy The center's y-axis
     * @param duration The duration of the animation
     * @param removesFromViewOnPush If true, the view being replaced will be removed from the view hierarchy on pushes
     */
    public CircularRevealChangeHandler(int cx, int cy, long duration, boolean removesFromViewOnPush) {
        super(duration, removesFromViewOnPush);
        this.cx = cx;
        this.cy = cy;
    }



    @Override
    protected AnimatorGroup getAnimator(ComponentContainer container, Component from, Component to, boolean isPush, boolean toAddedToContainer) {
        final float radius = (float) Math.hypot(cx, cy);
        AnimatorGroup animatorGroup = new AnimatorGroup();
        AnimatorProperty fromAnimatorProperty = null;
        AnimatorProperty toAnimatorProperty = null;
        if (isPush && to != null) {
            toAnimatorProperty = to.createAnimatorProperty();
            toAnimatorProperty.moveFromX(cx);
            toAnimatorProperty.moveFromY(cy);
            toAnimatorProperty.rotate(radius);

        } else if (!isPush && from != null) {
            fromAnimatorProperty = from.createAnimatorProperty();
            fromAnimatorProperty.moveFromX(cx);
            fromAnimatorProperty.moveFromY(cy);
            fromAnimatorProperty.rotate(radius);
        }
        if(fromAnimatorProperty != null && toAnimatorProperty != null){
            animatorGroup.runParallel(fromAnimatorProperty,toAnimatorProperty);
        }else if (fromAnimatorProperty != null){
            animatorGroup.runParallel(fromAnimatorProperty);
        }else if (toAnimatorProperty != null){
            animatorGroup.runParallel(toAnimatorProperty);
        }
        return animatorGroup;
    }

    @Override
    protected void resetFromView(Component from) {

    }
}
